package com.xingkeduo.service.impl;

import com.xingkeduo.controller.StaffClockInController;
import com.xingkeduo.dao.workpad.TStaffAttendanceMapper;
import com.xingkeduo.dao.workpad.TStaffClockInMapper;
import com.xingkeduo.model.bo.AttendanceWorkStatusEnum;
import com.xingkeduo.model.param.ClockInStatusParam;
import com.xingkeduo.model.param.TStaffClockInParam;
import com.xingkeduo.model.po.TStaffAttendance;
import com.xingkeduo.model.po.TStaffClockIn;
import com.xingkeduo.model.vo.StaffAttendanceStatusVo;
import com.xingkeduo.model.vo.StaffAttendanceVo;
import com.xingkeduo.service.StaffClockInService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.util.Date;
import java.util.List;

/**
 * @Description TODO
 * @Date 2019/3/26 10:19
 * @Created 情绪十分不稳定的Shadow
 */

@Service
public class StaffClockInServiceImpl implements StaffClockInService {


    private static Logger log = LoggerFactory.getLogger(StaffClockInServiceImpl.class);
    @Autowired
    private TStaffClockInMapper mapper;
    @Autowired
    private TStaffAttendanceMapper staffAttendanceMapper;

    /**
     * @description  记录打卡信息 && 变更发型师考勤表对应status
     * @Author 情绪极其不稳定的Shadow
     * @Param [staffClockIn, staffAttendanceId]
     * @return int
     **/
    @Transactional(readOnly = false)
    @Override
    public int saveStaffClockIn(TStaffClockInParam param) {
        Date realityTime = new Date();
        int endWorkStatus = 0;
        int startWorkStatus = 0;
        TStaffAttendance staffAttendance = staffAttendanceMapper.selectByPrimaryKey(param.getStaffAttendanceId());
        if(null == staffAttendance){
            return 0;
        }
        Boolean startFlag = null;
        Boolean endFlag = null;
        log.info("param.getType() == "+param.getType());
        //上班打卡
        if(param.getType() == 1){
        log.info("staffAttendance.getStartTime()=="+staffAttendance.getStartTime());
            //验证是否有上班时间  获取时间对比结果 startFlag = true 迟到  startFlag = false 正常
            if(null != staffAttendance.getStartTime()){
                startFlag = attendanceJudge(staffAttendance.getStartTime(), realityTime);
                //获取对比后 考勤状态 枚举
                if(startFlag){
                    startWorkStatus = AttendanceWorkStatusEnum.NORMAL_TIME.getValue();
                }else {
                    startWorkStatus = AttendanceWorkStatusEnum.LATE_TIME.getValue();
                }
            }
        log.info("startWorkStatus--->>>"+startWorkStatus);
        }
        //下班打卡
        if(param.getType() == 2){
            //验证是否有下班时间  获取时间对比结果 endFlag = true 早退 endFlag = false 正常
            log.info("staffAttendance.getEndTime()=="+staffAttendance.getEndTime());
            if(null != staffAttendance.getEndTime()){
                endFlag = attendanceJudge(staffAttendance.getEndTime(), realityTime);
                //获取对比后 考勤状态 枚举
                if(null != endFlag){
                    if(!endFlag){
                        endWorkStatus = staffAttendance.getWorkStatus();
                    }else{
                        if(staffAttendance.getWorkStatus() == 1){
                            endWorkStatus = AttendanceWorkStatusEnum.LATE_LEAVE_EARLY_TIME.getValue();
                        }else{
                            endWorkStatus = AttendanceWorkStatusEnum.LEAVE_EARLY_TIME.getValue();
                        }
                    }
                }
            log.info("endWorkStatus--->>>"+endWorkStatus);
            }
        }
        //根据type判断打卡状态 type = 1 上班卡  type = 2 下班卡
        //1、修改考勤表状态 考勤表打卡时间
        if(param.getType() == 1){
            staffAttendanceMapper.updateByStaffAttendanceId(param.getStaffAttendanceId(), realityTime,null, true, startWorkStatus);
        }else if(param.getType() == 2){
            staffAttendanceMapper.updateByStaffAttendanceId(param.getStaffAttendanceId(), staffAttendance.getRealWorkStartTime(), realityTime, false, endWorkStatus);
        }else{
            staffAttendanceMapper.updateByStaffAttendanceId(param.getStaffAttendanceId(), null,null, true, staffAttendance.getWorkStatus());
        }
        //2、insert打卡流水表记录
        TStaffClockIn staffClockIn = conver(param);
        int insert = mapper.insert(staffClockIn);
        return insert;
    }


    /**
     * 判断打卡状态
     * @param staffId
     * @return
     */
    @Override
    public StaffAttendanceVo getStaffClockInStatus(Long staffId) {
        SimpleDateFormat simdfDate = new SimpleDateFormat("yyyy-MM-dd");
        String selectDate = simdfDate.format(new Date());
        List<TStaffAttendance> staffAttendanceByStaffId = staffAttendanceMapper.selectByStaffIAndDateOfClockIn(staffId, selectDate);
        StaffAttendanceVo staffAttendanceVo = null;
        for(TStaffAttendance attendance : staffAttendanceByStaffId){
            if(attendance.getStatus()){
                staffAttendanceVo = new StaffAttendanceVo(attendance, null);
            }
        }
        if(null == staffAttendanceVo){
            return null;
        }
        return staffAttendanceVo;
    }

    /**
     * @description 打卡前查询考勤状态
     * @Author 情绪极其不稳定的Shadow
     * @Param [param]
     * @return int
     **/
    @Override
    public StaffAttendanceStatusVo getClockInStatus(ClockInStatusParam param) {
        SimpleDateFormat format = new SimpleDateFormat("HH:mm");
        Boolean flag = null;
        Date realityTime = new Date();
        StaffAttendanceStatusVo statusVo = new StaffAttendanceStatusVo();
        TStaffAttendance staffAttendance = staffAttendanceMapper.selectByPrimaryKey(param.getStaffAttendanceId());
        if(null == staffAttendance){
            return null;
        }
        //根据type判断打卡状态 type = 1 上班卡  type = 2 下班卡
        //1、修改考勤表状态 考勤表打卡时间
        statusVo.setNowTime(format.format(new Date()));
        if(param.getType() == 1){
            flag = attendanceJudge(staffAttendance.getStartTime(), realityTime);
            statusVo.setClockInTime(format.format(staffAttendance.getStartTime()));
            //flag = true 迟到  flag = false 正常
            if(flag){
                statusVo.setWorkStatus(AttendanceWorkStatusEnum.NORMAL_TIME.getValue());
                return statusVo;
            }else {
                statusVo.setWorkStatus(AttendanceWorkStatusEnum.LATE_TIME.getValue());
                return statusVo;
            }
        }else{
            flag = attendanceJudge(staffAttendance.getEndTime(), realityTime);
            //先判断是否早退 flag = true 早退 flag = false 正常
            statusVo.setClockInTime(format.format(staffAttendance.getEndTime()));
            if(!flag){
                statusVo.setWorkStatus(AttendanceWorkStatusEnum.NORMAL_TIME.getValue());
                return statusVo;
            }else{
                //是否迟到
                if(staffAttendance.getWorkStatus() == 1){
                    statusVo.setWorkStatus(AttendanceWorkStatusEnum.LATE_LEAVE_EARLY_TIME.getValue());
                    return statusVo;
                }else{
                    statusVo.setWorkStatus(AttendanceWorkStatusEnum.LEAVE_EARLY_TIME.getValue());
                    return statusVo;
                }
            }
        }
    }


    private TStaffClockIn conver(TStaffClockInParam param){
        TStaffClockIn staffClockIn = new TStaffClockIn();
        staffClockIn.setStaffId(param.getStaffId());
        staffClockIn.setStaffName(param.getStaffName());
        staffClockIn.setStoreId(param.getStoreId());
        staffClockIn.setStoreName(param.getStoreName());
        staffClockIn.setDate(new Date());
        if(param.getType() == 1 || param.getType() == 3){
            staffClockIn.setRealWorkStartTime(new Date());
        }else{
            staffClockIn.setRealWorkStopTime(new Date());
        }
        staffClockIn.setEnable(true);
        return staffClockIn;
    }

    private Boolean attendanceJudge(Date planTime, Date realityTime){

        Instant instantReality = realityTime.toInstant();
        ZoneId zoneReality = ZoneId.systemDefault();
        LocalDateTime localDateTimeReality = LocalDateTime.ofInstant(instantReality, zoneReality);
        LocalTime localTimeReality = localDateTimeReality.toLocalTime();

        Instant instantPlan = planTime.toInstant();
        ZoneId zonePlan = ZoneId.systemDefault();
        LocalDateTime localDateTimePlan = LocalDateTime.ofInstant(instantPlan, zonePlan);
        LocalTime localTimePlan = localDateTimePlan.toLocalTime();

        if(localTimePlan.isBefore(localTimeReality)){
            return false;
        }
        return true;
    }

}
